<?php
/**
 * mpPackager copy.
 *
 * @category    Development
 * @package 	mpPackager
 * @subpackage  Copy
 * @author		Murat Purc <murat@purc.de>
 * @copyright   Copyright (c) 2009-2010 Murat Purc (http://www.purc.de)
 * @license     http://www.gnu.org/licenses/gpl-2.0.html - GNU General Public License, version 2
 * @version     $Id: Copy.php 2 2010-04-11 18:09:46Z purcaholic $
 */


/**
 * Packager copy class.
 *
 * @category    Development
 * @package 	mpPackager
 * @subpackage  Copy
 * @author		Murat Purc <murat@purc.de>
 */
class mpPackager_Copy
{
    private $_debug = false;

    private $_folderPerms = 0755;

    private $_filePerms = 0644;

    private $_msg = array();

    /**
     * Constructor
     * @return  void
     */
    public function __construct()
    {
    }


    /**
     * Debug setter. If set to true, copy process runs in test mode, means that without 
     * changes on file system!
     *
     * @param  bool  $debug
     */
    public function setDebug($debug)
    {
        $this->_debug = (bool) $debug;
    }


    /**
     * Folder permissions setter.
     *
     * @param  int  $folderPerms
     */
    public function setFolderPerms($folderPerms)
    {
        $this->_folderPerms = $folderPerms;
    }


    /**
     * File permissions setter.
     *
     * @param  int  $filePerms
     */
    public function setFilePerms($filePerms)
    {
        $this->_filePerms = $filePerms;
    }


    /**
     * Returns collected messages.
     *
     * @param   bool   $reset  Flag to reset collected messages aftern return.
     * @return  array  Indexed list of messages
     */
    public function getMessages($reset=false)
    {
        $msg = $this->_msg;
        if ($reset) {
            $this->_msg = array();
        }
        return $msg;
    }


    /**
     * Recursive copy from source to destination!
     *
     * source=file & dest=dir => copy file from source-dir to dest-dir
     * source=file & dest=file / not there yet => copy file from source-dir to dest and overwrite a file there, if present
     *
     * source=dir & dest=dir => copy all content from source to dir
     * source=dir & dest not there yet => copy all content from source to a, yet to be created, dest-dir
     *
     * @param   string  $source
     * @param   string  $dest
     * @return  boolean
     */
    public function recursive($source, $dest)
    {
        $result = false;

        if (is_file($source)) {
            // $source is file
            $result = $this->copyFile($source, $dest);
        } elseif (is_dir($source)) {

            // ########## $source is dir

            if (!is_dir($dest)) {
                $this->_msg[] = "mkdir: $dest; chmod: $this->_filePerms";
                if (!$debug) {
                    // dest-dir not there yet, create it
                    @mkdir($dest, $this->_folderPerms);
                    chmod($dest, $this->_folderPerms);
                }
            }
            if ($source[strlen($source)-1] != '/') {
                // add '/' if necessary
                $source = $source . '/';
            }
            if ($dest[strlen($dest)-1] != '/') {
                // add '/' if necessary
                $dest = $dest . '/';
            }

            // find all elements in $source
            $result = true; # in case this dir is empty it would otherwise return false
            $dirHandle = opendir($source);
            while ($file = readdir($dirHandle)) { # note that $file can also be a folder
                if($file != '.' && $file != '..') { # filter starting elements and pass the rest to this function again
    #                echo "$source$file ||| $dest$file<br />\n";
                    $result = $this->recursive($source . $file, $dest . $file);
                }
            }
            closedir($dirHandle);

        } else {

            // ########## $source is either a file nor a dir

            $result = false;
        }
        return $result;
    }


    public function copyFile($source, $dest)
    {
        if (!is_file($source)) {
            throw new mpPackagerException("mpPackager_Copy->copyFile(): Source $source is not a file.");
        }

        $result = false;

        if (is_dir($dest)) {
            // $dest is folder
            if ($dest[strlen($dest)-1] != '/') {
                // add '/' if necessary
                $destNew = $dest . '/';
            }
            $destNew .= basename($source);
        } else {
            // $dest is (new) filename
            $destNew = $dest;
        }
        $this->_msg[] = "copy: $source -> $dest; chmod: $this->_filePerms";
        if (!$debug) {
            $result = copy($source, $destNew);
            chmod($destNew, $this->_filePerms);
        }
        return $result;
    }

}
